using UnityEngine;
using System.Collections;

/**
 * Basically we orbit with some up-and-down movement
 * up-and-down is in the direction of the normal, so we'll call it y-movement.
 * x-movement will be tangent to the circle
 * It'll look like a sine wave
 */
public class OrbitCircleWavy : OrbitCircle {
	private float y_angle = 0;
	private const float Y_ANGLE_SCALE = 10;
	private const float MAX_Y_MOVEMENT = 0.75f;
	
	public OrbitCircleWavy(GameObject center, Vector3 normal, float radius, float orbit_speed) :
		base(center, normal, radius, orbit_speed) {
	}
	/**
	 * @param curr_pos: generally going to be this.transform.position
	 * @param delta_time: generally going to be Time.deltaTime from an Update() call
	 */
	public override Vector3 GetNextPos(Vector3 curr_pos, float delta_time) {
		Vector3 plane_vector;
		Vector3 dest_pos;
		float angle;
		float distance_to_travel;
		Quaternion rotation;
		float y_movement;
		
		this.UpdateFromCenter ();
		
		distance_to_travel = this.speed * delta_time;
		if (distance_to_travel < OrbitCircle.MIN_DISTANCE) {
			distance_to_travel = OrbitCircle.MIN_DISTANCE;
		}
		
		/* If we travel 25% of the circumference, then we do e.g. .25 * 360 to get 90 degrees */
		angle = 360.0f * distance_to_travel / this.circumference;
		rotation = Quaternion.AngleAxis (angle, this.unit_normal);
			
		dest_pos = this.ApplyQuaternion (this.GetClosestPointInCircle(curr_pos), rotation);
			
		/* Clamp to radius due to rounding and other issues */
		plane_vector = dest_pos - this.CenterPosition;
		dest_pos = this.CenterPosition + ((plane_vector * this.radius) / plane_vector.magnitude);
			
		/**
		 * Don't technically need to clamp to 360, but just for sanity
		 * Basically the steps are:
		 * 1. Increase y_angle based on delta time (imagine traversing the unit circle)
		 * 2. The y movement is just sine of y angle times the radius of the circle (i.e. max y movement)
		 * 3. We adjust the pos based on unit normal because the up-and-down is wrt the circle plane
		 */
		this.y_angle = (this.y_angle + (delta_time*OrbitCircleWavy.Y_ANGLE_SCALE)) % 360;
		y_movement = OrbitCircleWavy.MAX_Y_MOVEMENT*Mathf.Sin(this.y_angle);
		dest_pos = dest_pos + (this.unit_normal * y_movement);
		
		return dest_pos;
	}
}
